package de.hdu.mfz.dto;

import java.text.SimpleDateFormat;
import java.util.ArrayList;

import de.hdu.mfz.model.Route;
import de.hdu.mfz.model.Routenpunkt;

/** Eine Zeile für die Liste der Routen in der Anzeige. Also eine Route. Aber für
 * die Oberfläche aufbereitet.
 * 
 * @author ronin
 * 23.04.2012
 */
public class RouteZeile {

	/* Alle Eigenschaften der Klasse müssen public sein, damit 
	 * sie von der JSON View in einen JSON String umgewandelt werden können.
	 * Mit Getter Methoden funktioniert das leider nicht.*/
	public int id;
	public String zeit;
	public String anzeit;
	public String fahrer;
	public String platz;
	/* orte_kurz enthält nur die zwei Orte, nach denen gesucht wurde 
	 * und ein paar Zwischenhalte. Aber insgesamt nie mehr wie 5. Wenn
	 * die Route zuviele Zwischenhalte hat, dann werden diese mit ... ersetzt.
	 * orte_lang enthält alle Routenpunkte (Start+Zwischenhalte+Ziel).
	 * orte_kurz wird in Listen angezeigt. orte_lang in Detailansichten
	 * */
	public RouteZeile_Ort[] orte_kurz;
	public RouteZeile_Ort[] orte_lang;
	
	/** Konstruktor. Erstellt eine leeres RouteZeile-Objekt
	 * @param anzOrte: Anzahl der Felder in orte_kurz und orte_lang
	 */
	public RouteZeile(int anzOrte) {
		this.orte_kurz = new RouteZeile_Ort[anzOrte];
		this.orte_lang = new RouteZeile_Ort[anzOrte];
		for (int i = 0; i<anzOrte; i++) {
			this.orte_kurz[i]  = new RouteZeile_Ort();
			this.orte_lang[i]  = new RouteZeile_Ort();
		}
	}
	
	/** Konstruktor. Erstellt ein RouteZeile-Objekt für eine
	 * Route. Das Feld "platz" bleibt leer.
	 * @param myRoute: Route Objekt
	 * @param von: Startort (wird hervorgehoben)
	 * @param nach: Zieltort (wird hervorgehoben)
	 */
	public RouteZeile(Route myRoute, String von, String nach) {
		this(myRoute, von, nach, 0);
	}

	/** Konstruktor. Erstellt ein RouteZeile-Objekt für eine
	 * Route.
	 * @param myRoute: Route Objekt
	 * @param von: Startort (wird hervorgehoben)
	 * @param nach: Startort (wird hervorgehoben)
	 * @param belegtePlaetze: Anzahl belegte Plätze
	 */
	public RouteZeile(Route myRoute, String von, String nach, int belegtePlaetze) {
		this.id = myRoute.getRouteId();

		SimpleDateFormat dateConverter = new SimpleDateFormat("dd.MM.yyyy HH:mm");
		this.zeit = dateConverter.format(myRoute.getStartzeit());
		this.anzeit = dateConverter.format(myRoute.getZielzeit());
		
		
		//this.platz Beispiel: 3/5
		this.platz =  Integer.toString(belegtePlaetze).concat("/").concat(Integer.toString(myRoute.getPlaetze()));
		this.fahrer = myRoute.getFahrer().getAnzeigeName();
		
		int i=0;
		this.orte_lang = new RouteZeile_Ort[myRoute.getListe().size()];
		for (Routenpunkt rp : myRoute.getListe()){
			this.orte_lang[i++]=new RouteZeile_Ort(rp.getOrt());
		}
		
		
		/*Auf der Oberfläche wird nur ein Auszug aus den
		 * Routenpunkten angezeigt.
		 * Immer angezeigt werden:
		 * - Startpunkt,
		 * - Zielpunkt,
		 * - Start nach dem gesucht wurde
		 * - Ziel nach dem gesucht wurde.
		 * Andere Orte nur, wenn nicht mehr als zwei Zwischenhalte zwischen 
		 * zwei der oben aufgeführten Orte liegen. Ansonsten wird dazwischen
		 * nur ... angezeigt.
		 * 
		 * Beispiel:
		 * Routenpunkte: Wien, Linz, Passau, Iggensbach, Deggendorf
		 * Suche: von=Linz nach?Deggendorf
		 * Ergebnis: Wien, LINZ, ..., DEGGENDORF
		 * */
		boolean startFound=false;
		boolean zielFound=false;
		RouteZeile_Ort lastElement=null;
		boolean toAdd=false;
		boolean toHighlight=false;
		ArrayList<RouteZeile_Ort> tempResultList = new ArrayList<RouteZeile_Ort>();
		ArrayList<Routenpunkt> tempSourceList = new ArrayList<Routenpunkt>();
		for (Routenpunkt rp : myRoute.getListe()){
			tempSourceList.add(rp);
		}
		
		for (i=0; i<tempSourceList.size(); i++) { //schleife fängt erst bei 1 an, weil 0 vorhin
			Routenpunkt rp = tempSourceList.get(i);
			toAdd = false;
			toHighlight = false;
			
			if (i==0) { //start immer hinzufügen
				toAdd = true;
			}
			if (i==tempSourceList.size()-1) { //ziel immer hinzufügen
				toAdd = true;
			}
			
						
			if (rp.getOrt().toUpperCase().equals(von.toUpperCase()) && !startFound) { //startpunkt gefunden; strings immer in Großbuchstaben vergleichen, damit Groß-/Kleinschreibung egal ist
				toAdd = true;
				toHighlight = true;
				startFound = true; //falls ort mehrmals vorkommt, nur einmal hinzufügen / hervorheben
			}
			
			if (rp.getOrt().toUpperCase().equals(nach.toUpperCase()) && !zielFound && startFound) { //zielort gefunden. startFound, damit zielort nicht vor startort kommt
				toHighlight = true;
				toAdd = true;
				zielFound = true;
			}
			
			/*Wenn toAdd = true, dann muss der Punkt in der Oberfläche angezeigt werden. Wenn isHighlight
			 * gesetzt ist, dann wird er auch noch hervorgehoben.
			 * 
			 * Wenn nicht, dann ist es nur ein Zwischenhalt. Diese Funktion hier fügt Zwischenhalte erst in 
			 * die Ergebnisliste ein, sobald der nächste Punkt mit toAdd=true kommt. Bis dahin bleibt der letzte
			 * Zwischenhalt in der Variable lastElement gespeichert. Wenn mindestens zwei Zwischenhalte 
			 * hintereinander kommen, dann wir lastElement auf "..." gesetzt. 
			 * Dies ist der beste Algorithmus, der mit eingefallen ist, damit zwei oder mehr Zwischenhalte 
			 * zwischen zwei Punkte, die angezeigt werden müssen, durch "..." ersetzt werden.*/
			if (toAdd) {
				if (lastElement != null) {
					tempResultList.add(lastElement);
					lastElement = null;
				}
				
				tempResultList.add(new RouteZeile_Ort(toHighlight,rp.getOrt()));	
			} else {
				if (lastElement == null) {
					lastElement = new RouteZeile_Ort(rp.getOrt());
				} else {
					lastElement = new RouteZeile_Ort("...");
				}
			}
		}
		
		//orte array erstellen. tempResultList.toArray(); funktioniert leider nicht. Gibt Exception
		this.orte_kurz = new RouteZeile_Ort[tempResultList.size()];
		for (i=0; i<tempResultList.size(); i++) {
			this.orte_kurz[i] = tempResultList.get(i);
		}
		//
	}

	
	
}
